#include "qdoubanradio.h"
#include <QWebView>
#include <QtNetwork>
#include <QLayout>
#include <QFile>
#include <QDebug>
#include <cassert>
#include <QString>
#include <QCloseEvent>
#include <QSettings>
#include <QDataStream>
#include <QDateTime>

//<! FILE name
const QString COOKIES_FILE = "douban";
//<! URL
const QString DOUBAN_URL = "http://douban.fm/radio";

const quint32 JAR_VERSION = 23;
//<! serialize cookies
QDataStream& operator<<(QDataStream &stream, const QList<QNetworkCookie> &list)
{
    stream << JAR_VERSION;
    stream << quint32(list.size());
    for (int i = 0; i < list.size(); ++i)
        stream << list.at(i).toRawForm();
    return stream;
}
QDataStream& operator>>(QDataStream &stream, QList<QNetworkCookie> &list)
{
    list.clear();

    quint32 version;
    stream >> version;

    if (version != JAR_VERSION)
        return stream;

    quint32 count;
    stream >> count;
    for(quint32 i = 0; i < count; ++i)
    {
        QByteArray value;
        stream >> value;
        QList<QNetworkCookie> newCookies = QNetworkCookie::parseCookies(value);
        if (newCookies.count() == 0 && value.length() != 0) {
            qWarning() << "CookieJar: Unable to parse saved cookie:" << value;
        }
        for (int j = 0; j < newCookies.count(); ++j)
            list.append(newCookies.at(j));
        if (stream.atEnd())
            break;
    }
    return stream;
}

QDoubanRadio::QDoubanRadio(QWidget *parent)
    : QWidget(parent)
    //, has_cookie(false)
{
    //<! layout
    QHBoxLayout *layout = new QHBoxLayout;
    view = new QWebView;
    layout->addWidget(view);
    layout->setContentsMargins(0,0,0,0);
    setLayout(layout);
    //<! size
    setFixedSize(420, 186);

    //<! web setting below
    //<! enable plugin
    view->page()->settings()->setAttribute(QWebSettings::PluginsEnabled, true);;
    //<! load cookies
    load_cookies();

    //<! connect
    connect( view, SIGNAL(loadFinished(bool)), this, SLOT(load_finished()) );

    //<! start load
    view->load(QUrl("http://douban.fm/radio"));
}

QDoubanRadio::~QDoubanRadio()
{
}

void QDoubanRadio::load_finished()
{
    qDebug("load finished!");
}

void QDoubanRadio::save_cookies()
{
    QList<QNetworkCookie> cookies = view->page()->networkAccessManager()->cookieJar()->
                                    cookiesForUrl(QUrl(DOUBAN_URL));
    if ( cookies.empty() )
    {
        qDebug() << "no cookies to save!";
        return;
    }

    QSettings set(QSettings::IniFormat, QSettings::UserScope, "Dian", "QDoubanRadio");
    set.setValue( QLatin1String("cookies"), qVariantFromValue< QList<QNetworkCookie> >(cookies) );
}

void QDoubanRadio::load_cookies()
{
    assert(view);

    qRegisterMetaTypeStreamOperators< QList<QNetworkCookie> >("QList<QNetworkCookie>");
    QSettings set(QSettings::IniFormat, QSettings::UserScope, "Dian", "QDoubanRadio");
    QList<QNetworkCookie> cookies( qvariant_cast< QList<QNetworkCookie> >(set.value( QLatin1String("cookies"))) );

    //<! remove expired cookies
    for ( qint32 i = 0; i < cookies.size(); ++i )
    {
        if ( !cookies.at(i).isSessionCookie() )
        {
            QDateTime now = QDateTime::currentDateTime();
            if ( cookies.at(i).expirationDate() < now )
            {
                cookies.clear();
                break;
            }
        }
    }

    if ( cookies.empty() )
    {
        qDebug() << "no cookies!";
    }

    if ( view->page()->networkAccessManager()->cookieJar()->setCookiesFromUrl(cookies, QUrl(DOUBAN_URL)) )
    {
        qDebug() << "cookies load!";
    }
}

void QDoubanRadio::closeEvent(QCloseEvent *event)
{
    save_cookies();
    event->accept();
}
